package com.ncs.erp.view;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import javax.annotation.Resource;
import javax.ejb.SessionContext;
import javax.ejb.Stateful;
import javax.enterprise.context.Conversation;
import javax.enterprise.context.ConversationScoped;
import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.inject.Inject;
import javax.inject.Named;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.PersistenceContextType;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import com.ncsc.erp.model.SysTitleName;
import com.ncsc.erp.model.HrEmp;
import com.ncsc.erp.model.MmSupplier;
import com.ncsc.erp.model.MmSupplierContact;
import com.ncsc.erp.model.PcPurchaseOrder;
import com.ncsc.erp.model.PcPurchaseOrderSupplierContact;
import com.ncsc.erp.model.PcPurchaseReq;
import com.ncsc.erp.model.SdCust;
import com.ncsc.erp.model.SdCustContact;
import com.ncsc.erp.model.SdQuotation;
import com.ncsc.erp.model.SdQuotationCustContact;
import com.ncsc.erp.model.SdSaleOrder;
import com.ncsc.erp.model.SdSaleOrderCustContact;
import com.ncsc.erp.model.SysCompany;
import com.ncsc.erp.model.SysLanguage;
import com.ncsc.erp.model.SysTitleNameGroup;
import java.util.Iterator;

/**
 * Backing bean for SysTitleName entities.
 * <p>
 * This class provides CRUD functionality for all SysTitleName entities. It focuses
 * purely on Java EE 6 standards (e.g. <tt>&#64;ConversationScoped</tt> for
 * state management, <tt>PersistenceContext</tt> for persistence,
 * <tt>CriteriaBuilder</tt> for searches) rather than introducing a CRUD framework or
 * custom base class.
 */

@Named
@Stateful
@ConversationScoped
public class SysTitleNameBean implements Serializable
{

   private static final long serialVersionUID = 1L;

   /*
    * Support creating and retrieving SysTitleName entities
    */

   private Short id;

   public Short getId()
   {
      return this.id;
   }

   public void setId(Short id)
   {
      this.id = id;
   }

   private SysTitleName sysTitleName;

   public SysTitleName getSysTitleName()
   {
      return this.sysTitleName;
   }

   @Inject
   private Conversation conversation;

   @PersistenceContext(type = PersistenceContextType.EXTENDED)
   private EntityManager entityManager;

   public String create()
   {

      this.conversation.begin();
      return "create?faces-redirect=true";
   }

   public void retrieve()
   {

      if (FacesContext.getCurrentInstance().isPostback())
      {
         return;
      }

      if (this.conversation.isTransient())
      {
         this.conversation.begin();
      }

      if (this.id == null)
      {
         this.sysTitleName = this.example;
      }
      else
      {
         this.sysTitleName = findById(getId());
      }
   }

   public SysTitleName findById(Short id)
   {

      return this.entityManager.find(SysTitleName.class, id);
   }

   /*
    * Support updating and deleting SysTitleName entities
    */

   public String update()
   {
      this.conversation.end();

      try
      {
         if (this.id == null)
         {
            this.entityManager.persist(this.sysTitleName);
            return "search?faces-redirect=true";
         }
         else
         {
            this.entityManager.merge(this.sysTitleName);
            return "view?faces-redirect=true&id=" + this.sysTitleName.getTitleNameNo();
         }
      }
      catch (Exception e)
      {
         FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(e.getMessage()));
         return null;
      }
   }

   public String delete()
   {
      this.conversation.end();

      try
      {
         SysTitleName deletableEntity = findById(getId());
         SysTitleNameGroup sysTitleNameGroup = deletableEntity.getSysTitleNameGroup();
         sysTitleNameGroup.getSysTitleNames().remove(deletableEntity);
         deletableEntity.setSysTitleNameGroup(null);
         this.entityManager.merge(sysTitleNameGroup);
         SysLanguage sysLanguage = deletableEntity.getSysLanguage();
         sysLanguage.getSysTitleNames().remove(deletableEntity);
         deletableEntity.setSysLanguage(null);
         this.entityManager.merge(sysLanguage);
         Iterator<SysCompany> iterSysCompanies = deletableEntity.getSysCompanies().iterator();
         for (; iterSysCompanies.hasNext();)
         {
            SysCompany nextInSysCompanies = iterSysCompanies.next();
            nextInSysCompanies.setSysTitleName(null);
            iterSysCompanies.remove();
            this.entityManager.merge(nextInSysCompanies);
         }
         Iterator<SdSaleOrderCustContact> iterSdSaleOrderCustContacts = deletableEntity.getSdSaleOrderCustContacts().iterator();
         for (; iterSdSaleOrderCustContacts.hasNext();)
         {
            SdSaleOrderCustContact nextInSdSaleOrderCustContacts = iterSdSaleOrderCustContacts.next();
            nextInSdSaleOrderCustContacts.setSysTitleName(null);
            iterSdSaleOrderCustContacts.remove();
            this.entityManager.merge(nextInSdSaleOrderCustContacts);
         }
         Iterator<MmSupplier> iterMmSuppliers = deletableEntity.getMmSuppliers().iterator();
         for (; iterMmSuppliers.hasNext();)
         {
            MmSupplier nextInMmSuppliers = iterMmSuppliers.next();
            nextInMmSuppliers.setSysTitleName(null);
            iterMmSuppliers.remove();
            this.entityManager.merge(nextInMmSuppliers);
         }
         Iterator<SdCust> iterSdCusts = deletableEntity.getSdCusts().iterator();
         for (; iterSdCusts.hasNext();)
         {
            SdCust nextInSdCusts = iterSdCusts.next();
            nextInSdCusts.setSysTitleName(null);
            iterSdCusts.remove();
            this.entityManager.merge(nextInSdCusts);
         }
         Iterator<PcPurchaseReq> iterPcPurchaseReqs = deletableEntity.getPcPurchaseReqs().iterator();
         for (; iterPcPurchaseReqs.hasNext();)
         {
            PcPurchaseReq nextInPcPurchaseReqs = iterPcPurchaseReqs.next();
            nextInPcPurchaseReqs.setSysTitleName(null);
            iterPcPurchaseReqs.remove();
            this.entityManager.merge(nextInPcPurchaseReqs);
         }
         Iterator<PcPurchaseOrderSupplierContact> iterPcPurchaseOrderSupplierContacts = deletableEntity.getPcPurchaseOrderSupplierContacts().iterator();
         for (; iterPcPurchaseOrderSupplierContacts.hasNext();)
         {
            PcPurchaseOrderSupplierContact nextInPcPurchaseOrderSupplierContacts = iterPcPurchaseOrderSupplierContacts.next();
            nextInPcPurchaseOrderSupplierContacts.setSysTitleName(null);
            iterPcPurchaseOrderSupplierContacts.remove();
            this.entityManager.merge(nextInPcPurchaseOrderSupplierContacts);
         }
         Iterator<SdQuotationCustContact> iterSdQuotationCustContacts = deletableEntity.getSdQuotationCustContacts().iterator();
         for (; iterSdQuotationCustContacts.hasNext();)
         {
            SdQuotationCustContact nextInSdQuotationCustContacts = iterSdQuotationCustContacts.next();
            nextInSdQuotationCustContacts.setSysTitleName(null);
            iterSdQuotationCustContacts.remove();
            this.entityManager.merge(nextInSdQuotationCustContacts);
         }
         Iterator<SdCustContact> iterSdCustContacts = deletableEntity.getSdCustContacts().iterator();
         for (; iterSdCustContacts.hasNext();)
         {
            SdCustContact nextInSdCustContacts = iterSdCustContacts.next();
            nextInSdCustContacts.setSysTitleName(null);
            iterSdCustContacts.remove();
            this.entityManager.merge(nextInSdCustContacts);
         }
         Iterator<SdSaleOrder> iterSdSaleOrders = deletableEntity.getSdSaleOrders().iterator();
         for (; iterSdSaleOrders.hasNext();)
         {
            SdSaleOrder nextInSdSaleOrders = iterSdSaleOrders.next();
            nextInSdSaleOrders.setSysTitleName(null);
            iterSdSaleOrders.remove();
            this.entityManager.merge(nextInSdSaleOrders);
         }
         Iterator<PcPurchaseOrder> iterPcPurchaseOrders = deletableEntity.getPcPurchaseOrders().iterator();
         for (; iterPcPurchaseOrders.hasNext();)
         {
            PcPurchaseOrder nextInPcPurchaseOrders = iterPcPurchaseOrders.next();
            nextInPcPurchaseOrders.setSysTitleName(null);
            iterPcPurchaseOrders.remove();
            this.entityManager.merge(nextInPcPurchaseOrders);
         }
         Iterator<MmSupplierContact> iterMmSupplierContacts = deletableEntity.getMmSupplierContacts().iterator();
         for (; iterMmSupplierContacts.hasNext();)
         {
            MmSupplierContact nextInMmSupplierContacts = iterMmSupplierContacts.next();
            nextInMmSupplierContacts.setSysTitleName(null);
            iterMmSupplierContacts.remove();
            this.entityManager.merge(nextInMmSupplierContacts);
         }
         Iterator<HrEmp> iterHrEmps = deletableEntity.getHrEmps().iterator();
         for (; iterHrEmps.hasNext();)
         {
            HrEmp nextInHrEmps = iterHrEmps.next();
            nextInHrEmps.setSysTitleName(null);
            iterHrEmps.remove();
            this.entityManager.merge(nextInHrEmps);
         }
         Iterator<SdQuotation> iterSdQuotations = deletableEntity.getSdQuotations().iterator();
         for (; iterSdQuotations.hasNext();)
         {
            SdQuotation nextInSdQuotations = iterSdQuotations.next();
            nextInSdQuotations.setSysTitleName(null);
            iterSdQuotations.remove();
            this.entityManager.merge(nextInSdQuotations);
         }
         this.entityManager.remove(deletableEntity);
         this.entityManager.flush();
         return "search?faces-redirect=true";
      }
      catch (Exception e)
      {
         FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(e.getMessage()));
         return null;
      }
   }

   /*
    * Support searching SysTitleName entities with pagination
    */

   private int page;
   private long count;
   private List<SysTitleName> pageItems;

   private SysTitleName example = new SysTitleName();

   public int getPage()
   {
      return this.page;
   }

   public void setPage(int page)
   {
      this.page = page;
   }

   public int getPageSize()
   {
      return 10;
   }

   public SysTitleName getExample()
   {
      return this.example;
   }

   public void setExample(SysTitleName example)
   {
      this.example = example;
   }

   public void search()
   {
      this.page = 0;
   }

   public void paginate()
   {

      CriteriaBuilder builder = this.entityManager.getCriteriaBuilder();

      // Populate this.count

      CriteriaQuery<Long> countCriteria = builder.createQuery(Long.class);
      Root<SysTitleName> root = countCriteria.from(SysTitleName.class);
      countCriteria = countCriteria.select(builder.count(root)).where(
            getSearchPredicates(root));
      this.count = this.entityManager.createQuery(countCriteria)
            .getSingleResult();

      // Populate this.pageItems

      CriteriaQuery<SysTitleName> criteria = builder.createQuery(SysTitleName.class);
      root = criteria.from(SysTitleName.class);
      TypedQuery<SysTitleName> query = this.entityManager.createQuery(criteria
            .select(root).where(getSearchPredicates(root)));
      query.setFirstResult(this.page * getPageSize()).setMaxResults(
            getPageSize());
      this.pageItems = query.getResultList();
   }

   private Predicate[] getSearchPredicates(Root<SysTitleName> root)
   {

      CriteriaBuilder builder = this.entityManager.getCriteriaBuilder();
      List<Predicate> predicatesList = new ArrayList<Predicate>();

      short titleNameNo = this.example.getTitleNameNo();
      if (titleNameNo != 0)
      {
         predicatesList.add(builder.equal(root.get("titleNameNo"), titleNameNo));
      }
      SysTitleNameGroup sysTitleNameGroup = this.example.getSysTitleNameGroup();
      if (sysTitleNameGroup != null)
      {
         predicatesList.add(builder.equal(root.get("sysTitleNameGroup"), sysTitleNameGroup));
      }
      SysLanguage sysLanguage = this.example.getSysLanguage();
      if (sysLanguage != null)
      {
         predicatesList.add(builder.equal(root.get("sysLanguage"), sysLanguage));
      }
      String titleNameCode = this.example.getTitleNameCode();
      if (titleNameCode != null && !"".equals(titleNameCode))
      {
         predicatesList.add(builder.like(root.<String> get("titleNameCode"), '%' + titleNameCode + '%'));
      }
      String titleNameDescr = this.example.getTitleNameDescr();
      if (titleNameDescr != null && !"".equals(titleNameDescr))
      {
         predicatesList.add(builder.like(root.<String> get("titleNameDescr"), '%' + titleNameDescr + '%'));
      }

      return predicatesList.toArray(new Predicate[predicatesList.size()]);
   }

   public List<SysTitleName> getPageItems()
   {
      return this.pageItems;
   }

   public long getCount()
   {
      return this.count;
   }

   /*
    * Support listing and POSTing back SysTitleName entities (e.g. from inside an
    * HtmlSelectOneMenu)
    */

   public List<SysTitleName> getAll()
   {

      CriteriaQuery<SysTitleName> criteria = this.entityManager
            .getCriteriaBuilder().createQuery(SysTitleName.class);
      return this.entityManager.createQuery(
            criteria.select(criteria.from(SysTitleName.class))).getResultList();
   }

   @Resource
   private SessionContext sessionContext;

   public Converter getConverter()
   {

      final SysTitleNameBean ejbProxy = this.sessionContext.getBusinessObject(SysTitleNameBean.class);

      return new Converter()
      {

         @Override
         public Object getAsObject(FacesContext context,
               UIComponent component, String value)
         {

            return ejbProxy.findById(Short.valueOf(value));
         }

         @Override
         public String getAsString(FacesContext context,
               UIComponent component, Object value)
         {

            if (value == null)
            {
               return "";
            }

            return String.valueOf(((SysTitleName) value).getTitleNameNo());
         }
      };
   }

   /*
    * Support adding children to bidirectional, one-to-many tables
    */

   private SysTitleName add = new SysTitleName();

   public SysTitleName getAdd()
   {
      return this.add;
   }

   public SysTitleName getAdded()
   {
      SysTitleName added = this.add;
      this.add = new SysTitleName();
      return added;
   }
}